package com.m1.tzolkin.model.board;

import java.util.Collection;

import com.m1.tzolkin.model.TZResource;
import com.m1.tzolkin.model.exceptions.EndOfGameException;
import com.m1.tzolkin.model.exceptions.NoMovedWorkersException;
import com.m1.tzolkin.model.exceptions.NotEnoughCornException;
import com.m1.tzolkin.model.exceptions.WaitingOperationsException;
import com.m1.tzolkin.model.players.ITZPlayer;
import com.m1.tzolkin.model.temples.ITemple;

/**
 * Une extension du plateau de jeu.
 * Y ajoute la gestion des actions, des b�timents et des technologies.
 * Permet �galement de qu�mander du ma�s en d�but de tour.
 *
 */
public interface ITechBoard extends IBuildBoard {
	
	// REQUETES
	
	/**
	 * Retourne le nombre de niveau de technologie que le joueur courant peut monter.
	 */
	int canUpTechs();
	
	/**
	 * Retourne le nombre de temples dans lesquels le joueur courant doit descendre.
	 */
	int mustDownTemples();
	
	/**
	 * Retourne le nombre de niveaux de temples quelconques que le joueur courant peut monter.
	 */
	int canUpTemples();
	
	/**
	 * Retourne les temples dont le joueur courant peut monter d'une et une seule marche.
	 */
	Collection<ITemple> getUpableTemples();
	
	/**
	 * Retourne le nombre de temples diff�rents dont on peut monter d'une et une seule marche.
	 */
	int canUpDifferentTemples();
	
	/**
	 * Retourne true si le joueur courant peut �changer des ressources au march�.
	 */
	boolean canExchange();
	
	/**
	 * Retourne le nombre de ressources que le joueur peut choisir de prendre.
	 */
	int canCollectResource();

	// COMMANDES
	
	/**
	 * Qu�mande du ma�s au profit du joueur courant.
	 * Implique de descendre d'une marche dans un temple.
	 * @pre <pre>
	 *     getCurrentPlayer().getCorn() < LIMIT_CORN_FOR_ASK
	 *     getPlacedWorkers() == getRemovedWorkers() == 0 </pre>
	 * @post <pre>
	 *     getCurrentPlayer().getCorn() == LIMIT_CORN_FOR_ASK </pre>
	 */
	void askForCorn();
	
	/**
	 * Finit le tour.
	 * L�ve une exception si une op�ration est en attente (diminuer d'un temple...)
	 * Vide les actions disponibles � l'utilisateur.
	 */
	ITZPlayer endTurn() throws WaitingOperationsException, EndOfGameException, NoMovedWorkersException;

	/**
	 * Echange une unit� de ressource r contre du ma�s pour le joueur courant.
	 * @pre <pre>
	 *     isWaitingForTurn() == 0
	 *     r != null
	 *     getActualPlayer().getResource(r) >= 1
	 *     getPermissions().canExchange() </pre>
	 * @post <pre>
	 *     getActualPlayer().getResource(r) == getActualPlayer().getResource(r) - 1
	 *     getActualPlayer().getCorn() == old getActualPlayer().getCorn() + r.getCost() </pre>
	 */
	void changeResource(TZResource r);
	
	/**
	 * Echange des unit�s de ma�s contre une unit� de r pour le joueur courant.
	 * @pre <pre>
	 *     isWaitingForTurn() == 0
	 *     r != null
	 *     getActualPlayer().getCorn() >= r.getCost()
	 *     getPermissions().canExchange() </pre>
	 * @post <pre>
	 *     getActualPlayer().getResource(r) == old getActualPlayer().getResource(r) + 1
	 *     getActualPlayer().getCorn() == old getActualPlayer().getCorn() - r.getCost() </pre>
	 */
	void changeCorn(TZResource r) throws NotEnoughCornException;
	
	/**
	 * Permet de grimper de i technologies.
	 * @pre <pre>
	 *     i >= 0 </pre>
	 */
	void setTechEvolve(int i, boolean mustPay);
	
	/**
	 * Impose de descendre d'une marche dans i temples.
	 * @pre <pre>
	 *     i >= 0 </pre>
	 */
	void setDownTemples(int i);
	
	/**
	 * Permet de grimper dans i temples diff�rents.
	 * @pre <pre>
	 *     i >= 0 </pre>
	 */
	void setUpTemples(int i);
	
	/**
	 * Permet de grimper d'une marche dans i temples diff�rents.
	 * @pre <pre>
	 *     i >= 0 </pre>
	 */
	void setUpDifferentTemples(int i);

	/**
	 * Permet d'�changer son ma�s ou ses ressources.
	 */
	void setExchange(boolean can);
	
	/**
	 * Permet de choisir qty de ressources quelconques.
	 * @pre <pre>
	 *     qty >= 0 </pre>
	 */
	void setCollectResource(int qty);
	
}
